/* npm install -g typescript 命令行 tsc xxx.ts 转码js ，tsc --init 生成ts的相关配置 tsc --watch xxx.ts 直接就是边编译边监听
 
	ts-node xxx.ts直接在命令行运行
 */

//对象操作
/* 

	Object.assign用...结构代替合并,或者(<any>Object).assign
	parse,stringify,hasOwnProperty
	
 */
var obj:any = {sss:111}
var obj2:any = {sss2:111222}
var objstr:any = '{"ccc":111}';

// console.log({...obj,...obj2})
// console.log(JSON.stringify(JSON.parse(objstr)))

//数组处理
/* 

	push,unshift,concat
	pop,shift，，reverse//不用传参数
	splice,indexOf,join,some,every
	
 */
var arr:any = [1,20,3,4]
var arr2:any[] = [1,'20,3,4']
// console.log(arr2)

// console.log(arr.sort((a:any,b:any)=>{return a-b}))
// console.log(arr.some((v:any) => {return v>3}))
// console.log(arr.every((v:any) => {return v>0}))

//各种函数形式练习
/* 

	ts语言专场
	泛型，ts接口
	
	
 */
//###泛型
//泛型<>，其实就等同于函数中的，类型函数，其实尖括号也可以看成一个函数，只不过它只能传类型定义
//泛型传类型进去，‘或’可以这样写：<T>，然后传<Number | String>
//变量形式声明泛型，且只能type声明
type as<T> = T
type asNumber = as<Number>//只能传Object和Number和String和Boolean
type asStr = as<String>
//泛型无法以变量形式规定【变量的直接赋值类型】,且不可用
// var asvalue:asNumber = 111（不可用，改为type也不行）
//变量形式声明方法使用泛型,且只能js形式声明,且只能上面定义了泛型然后再使用
var asNumberfn:asNumber = 333//asNumber此时就是规定返回类型
var asStrfn:asStr = '333'//asStr此时就是规定返回类型
// console.log(asNumberfn())
// console.log(asStrfn())


//function声明方法并传具体类型或泛型，或使用泛型进行返回,传入的和返回规定的类型都是泛型，那返回值必须是传进来的参数
function a(a:any):any {
	//...a:any,传进去的规定类型，带中括号[]为规定数组类型
	//...():any,返回出来的规定类型,且调用的时候必须要有返回值
}

function b<T>(as:T):T {
	//...泛型直接<T>,然后参数也好，返回值也好，调用的时候，b<Number>(111)规定T的调用传参或返回的规则
	//...泛型即使有没有调用，有():T的都必须return个值出来
	//...fn定义的泛型只能尖括号传进去
	return as
}
// b<Number>(111)

//interface,给对象属性定义类型的一个对象接口，同时使用泛型（亦可不用）
//方法使用interface，写上去的参数不能打问号，都是必传的,定义的参数个数参数属性和参数规则中其中一个不一样也会报错
	//比如(b:Number,v?:String),(b:Number,v:String?)都会报错
interface objNumber<T> {
	ddd:T,
	bbb:T
}
interface objStr<T> {
	ddd:T,
	bbb:T
}
interface objStr_Num<T> {
	ddd:T,
	bbb:T
}

var aaan:objNumber<Number> = {
	ddd:11,
	bbb:33
}

var aaas:objStr<String> = {
	ddd:'111',
	bbb:'333'
}

var aaay:objStr_Num<Number | String> = {
	ddd:111,
	bbb:'333'
}
//interface还可以定义fn的传参类型【加】返回类型
interface fnprms {
	(b:Number,v:String):any
	//也可直接规定xxx()函数返回的类型，xxx():any
}
var interfn:fnprms = (b:Number,v:String):any => {
	return b
}

//多泛型

function TvK<T,K>(a:T,b:K):any {
	return a
}
// console.log(TvK<String,Number>('111',111))

//泛型里面调用泛型

type avv<T> = T
type avvStr = avv<String>
type avvNum = avv<Number>
type avv2<K> = K
type avv2Str = avv2<avvStr>
type avv2Num = avv2<avvNum>

var avv_str:avv2Str = '11'
var avv_num:avv2Num = 111

//继承
//具体的type和interface在泛型均可以继承，前提是对象
type objT = {
	msd:Number
}
interface objT2 {
	md:String
}
function bss<K,S extends objT>(m:S){
	return m
}
// console.log(bss<Number,any>({msd:111}))
// console.log(bss<Number,{}>({msd:111}))//出错
// console.log(bss<Number,{md:String,msd:Number}>({msd:111,md:'2342'}))//继承的对象也要写
// console.log(bss<Number,{md?:String}>({msd:111,md:'2342'}}))//出错
// console.log(bss<Number,{md:String}>({msd:111,md:'2342'}}))//出错
// console.log(bss<Number,{md:String,...objT}>({msd:111,md:'2342'}}))//出错

//interface继承type
interface objT3 extends objT {
	sk:Number
}
function bss2(s:objT3) {
	return s
}
// console.log(bss2({sk:111,msd:222}))

//interface继承类

class T4 {
	msk:Number;
	constructor(){
		this.msk = 2323
	}
}

var t4 = new T4()

interface objT4 extends T4 {
	mvs?:String
	mweewr:String
}
var objt4:objT4 = {
	// mvs:'1111',
	msk:2324,
	mweewr:'435435'
}